
/**************************************************START OF FILE*****************************************************/


/*------------------------------------------------------------------------------------------------------------------
Includes
*/
#include "stdint.h"
#include "stm32f1xx_hal.h"
#include "string.h"
#include "xAPP_UsbAudio.h"




#define EN_IIS_BYPASS 0

#define PLAY_BUFFER_SIZE (8*1024)	//播放缓冲区大小
#define RECO_BUFFER_SIZE (8*1024)	//录音缓冲区大小

/*------------------------------------------------------------------------------------------------------------------
Variables
*/


uint32_t IIS_RX_Buffer[IIS_BUFFER_SIZE];	//IIS缓冲区
uint32_t IIS_TX_Buffer[IIS_BUFFER_SIZE];	//IIS缓冲区



//播放缓冲控制
uint8_t PlayBuffer[PLAY_BUFFER_SIZE];
int32_t Play_Count = 0;
uint32_t Play_Writep = 0;
uint32_t Play_Readp = 0;
uint32_t Play_Start = 0;

//录音缓冲控制
uint8_t RecoBuffer[RECO_BUFFER_SIZE];
int32_t Reco_Count = 0;
uint32_t Reco_Writep = 0;
uint32_t Reco_Readp = 0;
uint32_t Reco_Start = 0;
uint32_t Reco_SendDataStart = 0;;



uint16_t CurrtentTimeCount = 0;


extern uint32_t CurrentSampleRate;
extern int16_t  CurrentVolumeSpeak;
extern int8_t muit_statusSpeak;


//标记是否有录音跟播放的中断
extern uint32_t isPlayOrReco;



uint32_t PLAY_CurrentBufferCount = 0;			//播放当前缓冲大小
uint16_t PLAY_USB_Time = 0;						//USB时间记录值 
uint16_t PLAY_IIS_Time = 0;						//IIS时间记录值


uint32_t RECO_CurrentBufferCount = 0;			//录音当前缓冲区大小
uint16_t RECO_USB_Time = 0;						//USB时间记录值 
uint16_t RECO_IIS_Time = 0;						//IIS时间记录值
uint32_t CurrentRecoLen = 48*6;


/*
*********************************************************************************************************************

@ Brief  : USB Audio播放数据接收

@ Param  : NONE

@ Return : NONE

@ Author : YWJ(QQ:872180981)

@ Data   : 2020-06-26 10:20

*********************************************************************************************************************
*/

void xAPP_ReceiveAudioDataCallBack(uint8_t* Buffer , uint32_t Len)
{
	auto int32_t Rxdata;

	
	//标记正在播放
	isPlayOrReco = 1;

    //写数据到缓冲区
    for (uint32_t i = 0; i < Len / 3; i++)
    {

        Rxdata = Buffer[2 + i * 3];
        Rxdata <<= 8;
        Rxdata |= Buffer[1 + i * 3];
        Rxdata <<= 8;
        Rxdata |= Buffer[0 + i * 3];
        Rxdata <<= 8;

		//音量处理不能用浮点数-浮点太慢
		Rxdata >>= 8;
        Rxdata *= CurrentVolumeSpeak;
		//静音处理
		if(muit_statusSpeak)
		{
			Rxdata = 0;
		}
		Rxdata /= 100;
		Rxdata<<=8;

        PlayBuffer[Play_Writep++] = Rxdata >> 16;
        PlayBuffer[Play_Writep++] = Rxdata >> 24;
        PlayBuffer[Play_Writep++] = 0;
        PlayBuffer[Play_Writep++] = Rxdata >> 8;


		if(Play_Writep >= PLAY_BUFFER_SIZE)
        {
            Play_Writep = 0;
        }
	}

    __disable_irq();
	PLAY_USB_Time = TIM2->CNT;
    Play_Count += ((Len / 3) * 4);
    __enable_irq();//打开所有中断

    if(Play_Start == 0)
    {
        if(Play_Writep > (PLAY_BUFFER_SIZE / 2))
        {
            Play_Start = 1;
        }
    }
}


/*
*********************************************************************************************************************

@ Brief  : USB  Audio录音数据发送

@ Param  : NONE

@ Return : NONE

@ Author : YWJ(QQ:872180981)

@ Data   : 2020-06-26 10:21

*********************************************************************************************************************
*/
extern int32_t SingleData[48];
int32_t DataReaeIndex = 0;
void xAPP_SendAudioDataFinishCallBack(uint8_t* Buffer , uint32_t* Len)
{
	//标记正在录音
	isPlayOrReco = 1;

    Reco_SendDataStart = 1;

    if(Reco_Start == 0)
    {
        memset(Buffer , 0x00 , 288);
        *Len = 288;
    }
    else
    {
        *Len = CurrentRecoLen;

		#define INPUTDATAMODE 0
        for (size_t i = 0; i < (*Len) / 3; i++)
        {
			#if(INPUTDATAMODE == 0)
			Buffer[1 + i * 3] = RecoBuffer[Reco_Readp++];

			Buffer[2 + i * 3] = RecoBuffer[Reco_Readp++];

			Reco_Readp++;
			Buffer[0 + i * 3] = RecoBuffer[Reco_Readp++];
			#elif(INPUTDATAMODE == 1)
			Buffer[1 + i * 3] = 0xDE;
			RecoBuffer[Reco_Readp++];
			Buffer[2 + i * 3] = 0xFD;
			RecoBuffer[Reco_Readp++];
			Reco_Readp++;
			Buffer[0 + i * 3] = 0xAA;
			RecoBuffer[Reco_Readp++];
			#elif(INPUTDATAMODE == 2)
			Buffer[1 + i * 3] = 0x00;
			RecoBuffer[Reco_Readp++];
			Buffer[2 + i * 3] = 0x00;
			RecoBuffer[Reco_Readp++];
			Reco_Readp++;
			Buffer[0 + i * 3] = 0x00;
			RecoBuffer[Reco_Readp++];

			#elif(INPUTDATAMODE == 4)
			Reco_Readp+=4;
			
			Buffer[1 + i * 3] = SingleData[DataReaeIndex] >> 16;
			Buffer[2 + i * 3] = SingleData[DataReaeIndex] >> 24;
			Buffer[0 + i * 3] = SingleData[DataReaeIndex] >> 8;

			DataReaeIndex++;
			if(DataReaeIndex == 48)
			{
				DataReaeIndex = 0;
			}

			#endif

			

            if(Reco_Readp >= RECO_BUFFER_SIZE)
            {
                Reco_Readp = 0;
            }
        }
        
        __disable_irq();
		RECO_USB_Time = TIM2->CNT;
        Reco_Count -= ((*Len/3) * 4);
        __enable_irq();//打开所有中断

        

        if(Reco_Count > 7* 1024)
        {
            Reco_Start = 0;
            Reco_Writep = 0;
            Reco_Readp = 0;
			Reco_Count = 0;
        }
        
    }


}


/*
*********************************************************************************************************************

@ Brief  : IIS 接收发送半满中断(中断间隔192个点，处理数据96个点，因为还有满中断) 4ms中断一次

@ Param  : NONE

@ Return : NONE

@ Author : YWJ(QQ:872180981)

@ Data   : 2020-06-21 17:01

*********************************************************************************************************************
*/
void HAL_SPI_TxRxHalfCpltCallback(SPI_HandleTypeDef *hspi)
{

	RECO_IIS_Time = TIM2->CNT;
    //******************************************************************************
    //播放相关
    #if(EN_IIS_BYPASS)
    //直通
	memcpy(IIS_TX_Buffer , IIS_RX_Buffer , IIS_BUFFER_SIZE * 2);

    #else

    if(Play_Start == 1)
    {
        uint8_t* Pbuffer = (uint8_t*)(&IIS_TX_Buffer[0]);
        for (uint32_t i = 0; i < IIS_BUFFER_SIZE *2 ; i++)
        {
            Pbuffer[i] = PlayBuffer[Play_Readp++];

            if(Play_Readp >= PLAY_BUFFER_SIZE)
            {
                Play_Readp = 0;
            }
        }
        __disable_irq(); //关闭所有中断
        Play_Count -= (IIS_BUFFER_SIZE *2);
        __enable_irq();//打开所有中断  

        if(Play_Count < 1024)
        {
            Play_Count = 0;
            Play_Writep = 0;
            Play_Readp = 0;
            Play_Start = 0;
        }
    }
    else
    {
        memset(&IIS_TX_Buffer[0] , 0 , IIS_BUFFER_SIZE * 2);
    }
    #endif


    //******************************************************************************
    //录音相关
    if(Reco_SendDataStart == 1)
    {
        uint8_t* p_Rx_Buffer = (uint8_t*)(&IIS_RX_Buffer[0]);
        for (uint32_t i = 0; i < IIS_BUFFER_SIZE * 2; i++)
        {
            RecoBuffer[Reco_Writep++] = p_Rx_Buffer[i];

            if(Reco_Writep >= RECO_BUFFER_SIZE)
            {
                Reco_Writep = 0;
            }
        }

        __disable_irq();
        Reco_Count += ((IIS_BUFFER_SIZE / 2) * 4);
        __enable_irq();//打开所有中断

        if(Reco_Start == 0)
        {
            if(Reco_Count > 4096)
            {
                Reco_Start = 1;
            }
        }
        //停止上传数据
        if(Reco_Count >= RECO_BUFFER_SIZE)
        {
            Reco_SendDataStart = 0;
            Reco_Writep = 0;
            Reco_Readp = 0;
            Reco_Count = 0;
            Reco_Start = 0;
        }
    }
}

/*
*********************************************************************************************************************
@ Brief  : IIS 接收发送中断(中断间隔192个点，处理数据96个点，因为还有半满中断) 4ms中断一次

@ Param  : NONE

@ Return : NONE

@ Author : YWJ(QQ:872180981)

@ Data   : 2021-10-01 09:57
*********************************************************************************************************************
*/
void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi)
{

    //******************************************************************************
    //播放相关

    #if(EN_IIS_BYPASS)
	memcpy(&IIS_TX_Buffer[IIS_BUFFER_SIZE/2] , &IIS_RX_Buffer[IIS_BUFFER_SIZE/2] , IIS_BUFFER_SIZE * 2);
    #else

    
    if(Play_Start == 1)
    {
        uint8_t* Pbuffer = (uint8_t*)(&IIS_TX_Buffer[IIS_BUFFER_SIZE/2]);
        for (uint32_t i = 0; i < IIS_BUFFER_SIZE * 2; i++)
        {
            Pbuffer[i] = PlayBuffer[Play_Readp++];
            if(Play_Readp >= PLAY_BUFFER_SIZE)
            {
                Play_Readp = 0;
            }
        }

        __disable_irq(); //关闭所有中断
		PLAY_IIS_Time = TIM2->CNT;
        Play_Count -= (IIS_BUFFER_SIZE *2);
        __enable_irq();//打开所有中断

        if(Play_Count < 1024)
        {
            Play_Count = 0;
            Play_Writep = 0;
            Play_Readp = 0;
            Play_Start = 0;
        }

		//******************************************************************************************
		//采样率校正(采样率反馈值计算)
		__disable_irq();
		PLAY_CurrentBufferCount = Play_Count + (((PLAY_IIS_Time - PLAY_USB_Time) * 10 ) / 208) * 8;
		__enable_irq();

		if(PLAY_CurrentBufferCount > (PLAY_BUFFER_SIZE/2) + 32)
		{
			CurrentSampleRate = 47990;
		}
		else if(PLAY_CurrentBufferCount < (PLAY_BUFFER_SIZE/2) - 32)
		{
				CurrentSampleRate = 48010;
		}
		else
		{
			CurrentSampleRate = 48000;
		}
    }
    else
    {
        memset(&IIS_TX_Buffer[IIS_BUFFER_SIZE/2] , 0 , IIS_BUFFER_SIZE * 2);
    }

    #endif

    //******************************************************************************
    //录音相关
    if(Reco_SendDataStart == 1)
    {
        uint8_t* p_Rx_Buffer = (uint8_t*)(&IIS_RX_Buffer[IIS_BUFFER_SIZE/2]);
        for (uint32_t i = 0; i < IIS_BUFFER_SIZE*2; i++)
        {
            RecoBuffer[Reco_Writep++] = p_Rx_Buffer[i];

            if(Reco_Writep >= RECO_BUFFER_SIZE)
            {
                Reco_Writep = 0;
            }
        }

        __disable_irq();
        Reco_Count += ((IIS_BUFFER_SIZE / 2) * 4);
		RECO_IIS_Time = TIM2->CNT;
        __enable_irq();//打开所有中断

        if(Reco_Start == 0)
        {
            if(Reco_Count > 4096)
            {
                Reco_Start = 1;
            }
        }

		__disable_irq();
		RECO_CurrentBufferCount = Reco_Count + (((RECO_IIS_Time - RECO_USB_Time) * 10 ) / 208) * 8;
		__enable_irq();//打开所有中断

		if(RECO_CurrentBufferCount > (PLAY_BUFFER_SIZE/2) + 32)
        {
			CurrentRecoLen = 49*6;
        }
        else if(RECO_CurrentBufferCount < (PLAY_BUFFER_SIZE/2) - 32)
        {
			CurrentRecoLen = 47*6;
        }
        else
        {
			CurrentRecoLen = 48*6;
        }

        //停止上传数据
        if(Reco_Count >= RECO_BUFFER_SIZE)
        {
            Reco_SendDataStart = 0;
            Reco_Writep = 0;
            Reco_Readp = 0;
            Reco_Count = 0;
            Reco_Start = 0;
        }
    }
}



/**************************************************END OF FILE*******************************************************/
